import React, {useEffect, useRef} from 'react';
import {Link, Outlet, useOutletContext, useLocation, useNavigate} from "react-router-dom";
import {App, Button, Card, Flex, Space, Statistic, Table} from "antd";
import LogFactory from "log/LogFactory";
import TableToolbar from "common/table/TableToolbar";
import reimburseDetailsColumns from "columns/ReimburseDetailsColumns";
import {useAppDispatch, useAppSelector} from "../../../../redux/hook";
import {ReimburseDetailState} from "../../../../redux/reducer/reimburseDetailReducer";
import {ThunkDispatch, UnknownAction} from "@reduxjs/toolkit";
import {NavigateFunction} from "react-router/dist/lib/hooks";
import ButtonGroup from "antd/es/button/button-group";
import {MessageInstance} from "antd/es/message/interface";
import {fetchListByReimburseId} from "../../../../redux/reducer/async/detailsAsyncAction";
import {fetchUpdateTotalAmount} from "../../../../redux/reducer/async/reimburseAsyncAction";
import {ReduxStatus} from "enum/ReduxStatus";

/**
 * 父组件共享数据给子组件的类型
 */
type ContextType = {
    /**
     * 报销单信息
     */
    reimburseId: number,
    /**
     * 报销单明细信息的Redux的状态
     */
    state: ReimburseDetailState,
    /**
     * 报销单明细信息的Redux的状态的dispatch
     */
    dispatch: ThunkDispatch<ReimburseDetailState, any, UnknownAction>,
    /**
     * 路由导航
     */
    navigate: NavigateFunction
    /**
     * 全局消息对象
     */
    message: MessageInstance

};

const log = LogFactory.getLog("Reimburse.Details");
let exeFlag: boolean = false;
const DetailsComponent = () => {

    const state = useAppSelector(state => state.reimburseDetail);

    const location = useLocation();
    const {reimburseId, totalAmount}: { reimburseId: number, totalAmount: number } = location.state;
    const pathname = location.pathname;
    const dispatch = useAppDispatch();
    const navigate = useNavigate();
    const {message} = App.useApp();
    const totalRef = useRef<number>();

    useEffect(() => {
        totalRef.current = totalAmount;
    }, []);

    /**
     * 当redux状态为init,并且报销单id大于0时,请求报销单明细信息
     */
    if (state.status === ReduxStatus.INIT && reimburseId > 0) {
        dispatch(fetchListByReimburseId(reimburseId));
    }
    /**
     * 当redux状态为success,并且报销单id和redux中的报销单id不一致时,刷新报销单明细信息
     */
    if (state.status === ReduxStatus.SUCCESS && state.reimburseId !== reimburseId) {
        dispatch(fetchListByReimburseId(reimburseId));
    }
    /**
     * 重置totalRef的值
     * 用户更新或者添加过报销记录后,退回此页面,不能使用页面传递的报销单总额
     */
    const resetTotalRef = () => {
        totalRef.current = state.totalMoney;
    };
    /**
     * 同步报销单的数量和金额
     */
    const syncReimburseTotalAmount = async () => {
        if (exeFlag) {
            log.info("同步方法执行中,拒绝执行");
            return;
        }
        if (totalRef.current === state.totalMoney) {
            message.info("数据没有更新");
            return;
        }
        exeFlag = true;
        let syncData = {
            id: state.reimburseId,
            totalAmount: state.totalMoney,
            itemCount: state.data.length
        };
        let res = await dispatch(fetchUpdateTotalAmount(syncData)).unwrap();
        if (res.data > 0) {
            totalRef.current = state.totalMoney;
            log.debug("报销单同步成功,重设[totalRef.current]", state.totalMoney, totalRef);
            resetTotalRef();
            message.success("报销单同步成功");
        } else {
            log.info("同步报销单失败",state.totalMoney,totalRef,totalAmount);
            message.error("报销单同步失败");
        }
        exeFlag = false;
    };
    /**
     * 报销单同步检测当报销单总额发生变化时,同步报销单
     */
    if (totalRef.current !== void 0 && pathname === "/nav/record/reimburse/details" && state.status === ReduxStatus.SUCCESS && totalRef.current !== state.totalMoney) {
        log.debug("同步报销单检测: ",totalAmount === state.totalMoney, totalAmount, state.totalMoney);
        setTimeout(syncReimburseTotalAmount, 1000);
    }

    const tableTitleRender = () => {
        return (
            <Flex justify={"space-between"}>
                <Space size={50}>
                    <ButtonGroup>
                        <Button type="primary">ID</Button>
                        <Button type="default">{reimburseId}</Button>
                    </ButtonGroup>
                    <Statistic title="总金额" value={state.totalMoney}/>
                    <Statistic title="Reimburse" value={totalAmount}/>
                    <Statistic title="TotalRef" value={totalRef.current}/>
                </Space>

                <Space size={10}>
                    <Button size={"small"} type={"primary"} key={"details-board"} onClick={() => navigate("./board",{state: {reimburseId, totalAmount}})}>看板</Button>
                    <Button size={"small"} type={"primary"} key={"details-option"} onClick={() => navigate("./option",{state: {reimburseId, totalAmount}})}>编辑选项</Button>
                    <Button size={"small"} type="primary" key={"details-sync"} onClick={syncReimburseTotalAmount}>同步数据</Button>
                </Space>

            </Flex>
        );
    };

    const refreshPage = () => {
        dispatch(fetchListByReimburseId(reimburseId));
    } ;

    return (
        <Card
            title="报销记录详细信息"
            extra={<Link to={".."}>报销单列表</Link>}
        >
            <TableToolbar linkState={{reimburseId, totalAmount}} titleContent={state.data.length} refresh={refreshPage}/>
            <Table
                title={tableTitleRender}
                loading={state.loading}
                dataSource={state.data}
                columns={reimburseDetailsColumns}
            />

            <Outlet context={{reimburseId, state, dispatch, navigate, message} satisfies ContextType}/>
        </Card>
    );
};

/**
 * 父组件共享数据给子组件
 * @returns 报销单信息和报销单明细信息
 */
export function useReimburseAndState() {
    return useOutletContext<ContextType>();
}

export default React.memo(DetailsComponent);